package com.aoip.telemetry.telemetry.core.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * crc 校验工具类
 *
 * @author chenbai
 * @version 1.0
 * @date 2021/6/11 14:31
 */
public class CrcCheckUtil {

    /**
     * 根据源16进制字符串计算crc值
     *
     * @param original 源16进制字符串
     * @return int 2字节16进制数 crc 16
     * @author chenbai
     * @date 2021/6/12
     **/
    public static int calCrc16(String original) {
        int crc = 0xFFFF;
        char[] chars = original.toCharArray();
        StringBuilder sb = new StringBuilder(2);
        int temp;
        int len = chars.length;
        for (int i = 0; i < len; i += 2) {
            sb.append(chars[i]).append(chars[i + 1]);
            temp = Integer.parseInt(sb.toString(), 16);
            crc = calOneByteCrc(temp, crc);
            sb.delete(0, 2);
        }
        return crc;
    }

    /**
     * 根据源16进制字符串和16进制crc字符串计算cec 有效性，crc有效返回true ， 否则返回false
     *
     * @param original 源16进制字符串
     * @param crc      输入16进制crc字符串
     * @return boolean
     * @author chenbai
     * @date 2021/6/12
     **/
    public static boolean checkCalCrc16(String original, String crc) {
        return Integer.parseInt(crc, 16) == calCrc16(original);
    }

    /**
     * 计算一个字节对应的crc值
     *
     * @param oneByte 一个完整字节
     * @param crc     crc 校验码
     * @return int
     * @author chenbai
     * @date 2021/6/12
     **/
    private static int calOneByteCrc(int oneByte, int crc) {
        crc = crc ^ oneByte;
        for (int i = 0; i < Byte.SIZE; i++) {
            if ((crc & 0x0001) == 0x0001) {
                crc >>= 1;
                crc ^= 0xA001;
            } else {
                crc >>= 1;
            }
        }
        return crc;
    }

    private static final DateTimeFormatter YMDHMS = DateTimeFormatter.ofPattern("yyMMddHHmmss");

    public static void main(String[] args) {
        String str = "B32202110B00C11537470000182918000009106000005010140A";

        int crc = 0x00;
        char[] chars = str.toCharArray();
        StringBuilder sb = new StringBuilder(2);
        int temp;
        int len = chars.length;
        for (int i = 0; i < len; i += 2) {
            sb.append(chars[i]).append(chars[i + 1]);
            temp = Integer.parseInt(sb.toString(), 16);
            crc = test02(temp, crc);
            sb.delete(0, 2);
        }
        System.out.println("=====" + crc);

    }

    private static int test02(int oneByte, int crc) {
        crc = crc ^ oneByte;
        for (int i = 0; i < Byte.SIZE; i++) {
            if ((crc & 0x0001) == 0x0001) {
                crc >>= 1;
                crc ^= 0x9;
            } else {
                crc >>= 1;
            }
        }
        return crc;
    }

    private static void swTest() {
        String msg = "7E7E011309012002000032101002000021100517021603";
        int i = calCrc16(msg);
        System.out.println("--" + Byte.SIZE);
        System.out.println();
        System.out.println(i);

        String serialNumber = "0000";
        String now = YMDHMS.format(LocalDateTime.now());
        String format = "%03X";
        int string = Integer.parseInt(Integer.toHexString(serialNumber.length() + now.length()));
        int len = serialNumber.length() + now.length();
        String length = String.format(format, string);
        String temp = String.format(format, len);
        System.out.println(length);
    }




}
